iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
自我挑戰組

打掉重練!Django的還債之旅~系列 第 28

Day28. 寫些test來測試我們的網頁!

  • 分享至 

  • xImage
  •  

前言

test測試,有了測試的保護以後要修改程式就比較不用怕出太多bug!
而測試寫熟了或測試的方式用熟了,還能挑戰TDD的開發方式,先寫測試在寫程式

紅燈 -> 綠燈 -> 重構

先寫測試也有一個好處是可以明確的自己知道專案進度如何,像我現在這樣回頭寫測試就會像為了寫測試而去測試的那種感覺,測試最重要的目的是保護我們的程式碼如期望中的運行,而這個期望就是我們最想要交付的東西~

而我在之前做個專案中都沒有寫過django的test,就讓我來研究研究要怎麼寫django的test吧!
我這邊的測試都是寫完後面在補的唷~改天再來試試看TDD!

正題

首先我們先來列下我們要測試的項目

  1. 測試views.index有正確渲染index.html,並回傳http status 200
  2. 測試views.api有正確回傳所有Todo data(預先setUp的資料)
  3. 測試views.add有如期新增資料
  4. 測試views.update有如期更新資料
  5. 測試views.delete有如期刪除資料

項目一

首先就先來寫第一個test 測試views.index吧
我們直接修改在todoapp中的tests.py

from django.test import TestCase, Client

class ToDoListTestCase(TestCase):
    def setUp(self) -> None:
        self.client = Client()
    
    
    def test_index(self):
        res = self.client.get("/")
        self.assertEqual(res.status_code, 200)
        self.assertTemplateUsed("index.html")

再來下指令python manage.py test
就會看到
https://ithelp.ithome.com.tw/upload/images/20231010/20162905ltCiadFf1S.png
內容大致為

  • 找到test
  • 建立test用database
  • run test
  • 結果
  • 刪掉test用database

明天就決定來看看test究竟做了什麼吧!

項目二

要測試api有沒有回傳所有data,要先塞給他預設的data

data = [
    {
        'id': 1,
        'title': 'test 001',
        'complete': False
    },
    {
        'id': 2,
        'title': 'test 002',
        'complete': True
    },
]

class ToDoListTestCase(TestCase):
    def setUp(self) -> None:
        # 新增資料
        Todo.objects.create(title=data[0]['title'], complete=data[0]['complete'])
        Todo.objects.create(title=data[1]['title'], complete=data[1]['complete'])
        
        # 建立client
        self.client = Client()
        
    # ...
    def test_get_all_todos(self):
        res = self.client.get("/api/")
        res_datas = json.loads(res.content)['data']
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res_datas[0]['title'], data[0]['title'])

這邊我先setUp了我上面定義好的data
接下來就去看看我們寫的views.py回傳什麼去處理,我們回傳的事JsonResponse所以需要先用json.loads處理後就是普通的data在跟我們原本定義的做比較

最後下python manage.py test
https://ithelp.ithome.com.tw/upload/images/20231010/20162905uItp9j75cc.png
沒有報錯,收工~

項目三

這邊要test的是新增,就來寫吧!
這邊要稍微注意,post過來的data型別

class ToDoListTestCase(TestCase):
    # ...
    def test_add_new_todo(self):
        test_data = {'title': 'test 003'}
        res = self.client.post(
                "/api/add/", 
                json.dumps(test_data), 
                content_type="application/json"
            )
        res_data = json.loads(res.content)
        self.assertEqual(res_data['todo_title'], test_data['title'])
        self.assertEqual(res_data['complete'], False)

新增完後一樣下python manage.py test
https://ithelp.ithome.com.tw/upload/images/20231010/20162905VEbfAY0cGh.png
看到OK後就完成

項目四

再來是test update complete的部分,直接寫吧~

class ToDoListTestCase(TestCase):
    # ...
    def test_update_todo(self):
        res = self.client.get(f"/api/update/{data[0]['id']}")
        res_data = json.loads(res.content)
        self.assertEqual(res_data['todo_id'], data[0]['id'])
        self.assertEqual(res_data['complete'], True)

測試修改預設data的第一筆資料是否complete
寫完一樣下python manage.py test
https://ithelp.ithome.com.tw/upload/images/20231010/20162905jplmyqR6ip.png
OK下面一位

項目五

test delete,開始

class ToDoListTestCase(TestCase):
    # ...
    def test_delete_todo(self):
        res = self.client.get(f"/api/delete/{data[0]['id']}")
        res_data = json.loads(res.content)
        self.assertEqual(res_data['todo_id'], data[0]['id'])
        todo = Todo.objects.filter(id=data[0]['id'])
        self.assertEqual(list(todo), [])

這邊我很簡單的去測試找條件為我們刪除的id還存不存在
寫完一樣python manage.py test
https://ithelp.ithome.com.tw/upload/images/20231010/20162905q0SfdyIO8e.png
OK大功告成~

那我這邊的測試項目都很簡單沒有用到太特別的框架或套件 e.g. seleninum or pytest等
做為我第一次寫test的開頭先簡單一點吧~

結語

測試這條路好像有很多東西可以玩,而且就寫測試這一點為出發點下去構想程式怎麼設計也是一個滿不錯的體驗,好的測試可以讓自己在開發的時候,像是完成一項一項的任務然後得到很多回饋感,再搭配CICD建立起來測完就推上去,之後再看自己git graph肯定會有滿滿的滿足感!之後的項目也要好好的寫測試!

完整的程式碼
https://github.com/m124578n/IronMan_ToDoList/blob/main/todolist/todoapp/tests.py


上一篇
Day27. 首先先來簡單做個Todolist頁面~
下一篇
Day29. test指令的過程和unittest的運作!
系列文
打掉重練!Django的還債之旅~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言